<template>
  <div class="player">
      <!-- @enter="enter"
      @after-enter="afterEnter"
      @leave="leave"
      @after-leave="afterLeave" -->
    <transition
      name="normal"
    >
      <div class="normal-player" v-if="fullScreen">
        <div class="background">
          <img width="100%" height="100%" :src="currentSong.image" />
        </div>
        <div class="top">
          <div class="back" @click="hideFullScreen">
            <i class="iconfont icon-back">&#xeb15;</i>
          </div>
          <h1 class="title">{{currentSong.name}}</h1>
          <h2 class="subtitle">{{currentSong.singer}}</h2>
        </div>
        <!-- 中间 -->
        <div class="middle">
          <div class="slider-wrap">
            <slider :autoPlay="false">
              <div class="middle-left">
                <div class="cd-wrapper" ref="cdWrapper">
                  <div class="cd" :class="pauseRotate">
                    <img class="image" :src="currentSong.image" />
                  </div>
                </div>
              </div>
              <div class="middle-right">
                <scroll ref="lyricList" class="lyric-list">
                  <div class="lyric-wrapper">
                    <div v-if="currentLyric">
                      <p
                        ref="lyricLine"
                        class="text"
                        :class="{'current': currentLineNum === index}"
                        v-for="(item, index) in currentLyric.lines"
                        :key="index"
                      >{{item.txt}}</p>
                    </div>
                  </div>
                </scroll>
              </div>
            </slider>
          </div>
        </div>
        <div class="bottom">
          <!-- 操作按钮 -->
          <div class="operators">
            <div @click.stop="changeMode">
              <i class="iconfont" v-html="modeIcon"></i>
            </div>
            <div @click.stop="handlePrev">
              <i class="iconfont">&#xe60c;</i>
            </div>
            <div @click.stop="togglePlaying">
              <i class="iconfont control-pause" v-html="playIcon"></i>
            </div>
            <div @click.stop="handleNext">
              <i class="iconfont">&#xe6a1;</i>
            </div>
            <div @click.stop="handlePlayList">
              <i class="iconfont">&#xe674;</i>
            </div>
          </div>
        </div>
      </div>
    </transition>
    <!-- mini播放器 -->
    <mini-player />
    <!-- 播放列表 -->
    <play-list />
    <audio
      ref="audio"
      :src="currentSong.url"
      @play="ready"
      @error="error"
      @timeupdate="updateTime"
      @ended="end"
    ></audio>
  </div>
</template>

<script>
import { mapGetters, mapMutations, mapActions } from 'vuex'
import { MODE_ICON } from 'utils/constant'
import MiniPlayer from './MiniPlayer'
import PlayList from './PlayList'
import Slider from 'baseUI/Slider'
import Scroll from 'baseUI/Scroll'
// 歌曲插件
import Lyric from 'lyric-parser'
/**
 * 插件Api
 * 播放歌词 play()
 * 暂停歌词 stop()
 * 歌词跳转 seek(startTime)
 * 切换播放/暂停状态 toggelePlay()
 */
import { rand } from 'utils'

export default {
  name: 'Player',
  components: {
    Slider,
    Scroll,
    MiniPlayer,
    PlayList
  },
  computed: {
    ...mapGetters([
      'fullScreen',
      'playStatus',
      'mode',
      'currentIndex',
      'currentSong',
      'showPlayList',
      'playList'
    ]),
    // 图片旋转状态
    pauseRotate () {
      return this.playStatus ? 'play' : 'play pause'
    },
    // 播放模式切换
    modeIcon () {
      return MODE_ICON[this.mode]
    },
    // 播放暂停图标
    playIcon () {
      return this.playStatus ? '&#xe669;' : '&#xe666;'
    }
  },
  data () {
    return {
      songReady: false,
      currentLyric: null, // 歌词
      currentLineNum: 0
    }
  },
  methods: {
    // 获取歌词
    getLyric () {
      this.currentSong.getLyric().then(lyric => {
        if (this.currentSong.lyric !== lyric) {
          return
        }
        this.currentLyric = new Lyric(lyric, this.handleLyric)
        if (this.playStatus) {
          this.currentLyric.play()
        }
      }).catch(() => {
        this.currentLyric = null
        this.currentLineNum = 0
      })
    },
    // Lyric插件的回调
    handleLyric ({ lineNum, txt }) {
      console.log('歌词', lineNum, txt)
      this.currentLineNum = lineNum
      if (lineNum > 5) {
        let lineEl = this.$refs.lyricLine[lineNum - 5]
        this.$refs.lyricList.scrollToElement(lineEl, 1000) // 滚动到元素
      } else {
        this.$refs.lyricList.scrollTo(0, 0, 1000) // 滚动到顶部
      }
    },
    // 隐藏全屏播放器
    hideFullScreen () {
      this.setFullScreen(false)
    },
    // 更改播放模式
    changeMode () {
      let modeNum = this.mode
      modeNum++
      let mode = modeNum > 2 ? 0 : modeNum
      this.setPlayMode(mode)
    },
    // 显示播放列表
    handlePlayList () {
      this.setPlayList(true)
    },
    // 切换播放、暂停
    togglePlaying () {
      this.setPlayingState(!this.playStatus)
      // 切换歌词状态
      if (this.currentLyric) {
        this.currentLyric.togglePlay()
      }
    },
    // 切换状态
    ...mapMutations({
      setPlayingState: 'SET_PLAYING_STATE',
      setPlayList: 'SET_SHOW_PLAYLIST',
      setFullScreen: 'SET_FULL_SCREEN',
      setPlayMode: 'SET_PLAY_MODE'
    }),
    ...mapActions([
      'savePlayHistory',
      'setCurrentIndex'
    ]),
    // 上一首
    handlePrev () {
      if (!this.songReady) {
        return
      }
      if (this.playList.length === 1) {
        this.loop()
        return
      } else {
        if (this.mode === 1) { // 随机播放
          this.setCurrentIndex(rand(this.playList.length))
        }
        let index = this.currentIndex - 1
        if (index < 0) {
          index = this.playList.length - 1
        }
        this.setCurrentIndex(index)
        if (!this.playStatus) {
          this.togglePlaying()
        }
      }
      this.songReady = false
    },
    // 下一首
    handleNext () {
      if (!this.songReady) {
        return
      }
      if (this.playList.length === 1) {
        this.loop()
        return
      } else {
        if (this.mode === 1) { // 随机播放
          this.setCurrentIndex(rand(this.playList.length))
        }
        let index = this.currentIndex + 1
        if (index === this.playList.length) {
          index = 0
        }
        this.setCurrentIndex(index)
        if (!this.playStatus) {
          this.togglePlaying()
        }
      }
      this.songReady = false
    },
    // 提示该音频已准备好开始播放
    ready () {
      this.songReady = true
      this.savePlayHistory(this.currentSong)
    },
    // 音频播放报错
    error () {
      this.songReady = true
    },
    // 获取播放时间
    updateTime (e) {
      this.currentTime = e.target.currentTime
    },
    // 歌曲播放完后的处理
    end () {
      if (this.mode === 2) {
        this.loop()
      } else {
        this.handleNext()
      }
    },
    // 单曲循环
    loop () {
      this.$refs.audio.currentTime = 0
      this.$refs.audio.play()
      if (this.currentLyric) {
        this.currentLyric.seek(0)
      }
    }
  },
  watch: {
    currentSong (newSong, oldSong) {
      if (!newSong.id) {
        return
      }
      if (newSong.id === oldSong.id) {
        return
      }
      if (this.currentLyric) {
        this.currentLyric.stop()
        this.currentTime = 0
        this.currentLineNum = 0
      }
      clearTimeout(this.timer)
      this.timer = setTimeout(() => {
        this.getLyric()
        this.$refs.audio.play()
        this.setPlayingState(true)
      }, 1000)
    },
    // 监听播放状态
    playStatus (newPlaying) {
      const audio = this.$refs.audio
      this.$nextTick(() => {
        newPlaying ? audio.play() : audio.pause()
      })
    }
  }
}
</script>

<style lang="less" scoped>
@import '~assets/style/variable';
@import '~assets/style/mixin';
.player {
  .normal-player {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    z-index: 199;
    background: @color-background;
    .background {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      z-index: -1;
      opacity: 0.6;
      filter: blur(20px);
    }
    .top {
      position: relative;
      margin-bottom: 25px;
      .back {
        position: absolute;
        top: 0;
        left: 6px;
        z-index: 50;
        .icon-back {
          display: block;
          padding: 9px;
          font-size: 30px;
          color: @color-theme;
          transform: rotate(-90deg);
        }
      }
      .title {
        width: 70%;
        margin: 0 auto;
        line-height: 40px;
        text-align: center;
        .no-wrap();
        font-size: @fs-large;
        color: @color-text;
      }
      .subtitle {
        line-height: 20px;
        text-align: center;
        font-size: @fs-medium;
        color: @color-text;
      }
    }
    .middle {
      position: fixed;
      top: 90px;
      left: 0;
      right: 0;
      bottom: 130px;
      .slider-wrap {
        position: relative;
        height: 100%;
        width: 100%;
        overflow: hidden;
      }
      .middle-left {
        .cd-wrapper {
          padding-top: 10%;
          width: 320px;
          height: 320px;
          margin: 0 auto;
          .cd {
            width: 85%;
            height: 85%;
            border: 10px solid rgba(255, 255, 255, 0.1);
            border-radius: 50%;
            margin: 0 auto;
            &.play {
              animation: rotate 20s linear infinite;
            }
            &.pause {
              animation-play-state: paused;
            }
            .image {
              width: 100%;
              height: 100%;
              border-radius: 50%;
            }
          }
        }
      }
      .middle-right {
        width: 100%;
        height: 100%;
        .lyric-list {
          max-height: 420px;
          overflow: hidden;
        }
        .lyric-wrapper {
          padding-top: 10%;
          width: 85%;
          margin: 0 auto;
          text-align: center;
          .text {
            line-height: 32px;
            color: @color-text-l;
            font-size: @fs-medium;
            word-wrap: break-word;
            word-break: break-all;
            white-space: pre-wrap;
            &.current {
              color: @color-theme;
            }
          }
        }
      }
    }
    // 操作
    .bottom {
      position: absolute;
      bottom: 20px;
      left: 0;
      right: 0;
      padding: 0 20px;
      .operators {
        display: flex;
        align-items: center;
        justify-content: space-between;
        > div {
          color: #fff;
          i {
            font-size: 35px;
          }
          .control-pause {
            font-size: 50px;
          }
        }
      }
    }
  }
}
@keyframes rotate {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>
